package com.skyable.account.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.skyable.account.entity.SysUser;
import com.skyable.account.entity.SysUserRole;
import com.skyable.account.mapper.UserMapper;
import com.skyable.account.service.IUserRoleService;
import com.skyable.account.service.IUserService;
import com.skyable.common.common.ResponseResult;
import com.skyable.common.common.ServiceResult;
import com.skyable.common.constants.exception.AccountExcpConstants;
import com.skyable.common.constants.param.CommonParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author GaoYuan
 * @title: UserServiceImpl
 * @projectName spring-cloud-demo
 * @description: TODO
 * @date 2021/3/2317:53
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, SysUser> implements IUserService {

    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private UserMapper userMapper;

    @Override
    public ServiceResult<Boolean> createCompanyTable(Long domainId) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        int result = userMapper.createTable(domainId + CommonParams.COMPANY_TABLE_NAME);
        serviceResult.setResult(result > 0);
        return serviceResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResult<SysUser> insertUser(SysUser sysUser, List<Long> roleList) {
        ServiceResult<SysUser> serviceResult = new ServiceResult<>();
        SysUser user = lambdaQuery().eq(SysUser::getUsername, sysUser.getUsername()).one();
        if(user != null) {
            serviceResult.setError(AccountExcpConstants.ERROR_CODE_USER_NAME_EXISTS,AccountExcpConstants.ERROR_MSG_USER_NAME_EXISTS);
            return serviceResult;
        }
        user = lambdaQuery().eq(SysUser::getPhone, sysUser.getPhone()).one();
        if(user != null) {
            serviceResult.setError(AccountExcpConstants.ERROR_CODE_USER_PHONE_EXISTS,AccountExcpConstants.ERROR_MSG_USER_PHONE_EXISTS);
            return serviceResult;
        }
        user = lambdaQuery().eq(SysUser::getEmail, sysUser.getEmail()).one();
        if(user != null) {
            serviceResult.setError(AccountExcpConstants.ERROR_CODE_USER_EMAIL_EXISTS,AccountExcpConstants.ERROR_MSG_USER_EMAIL_EXISTS);
            return serviceResult;
        }
        sysUser.setStatus(0);
        sysUser.setDelFlag(0);
        baseMapper.insert(sysUser);
        if(roleList != null && !roleList.isEmpty()) {
            List<SysUserRole> sysUserRoleList = generateUserRole(sysUser.getId(), roleList);
            userRoleService.saveBatch(sysUserRoleList);
        }

        serviceResult.setResult(sysUser);
        return serviceResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResult<SysUser> updateUser(SysUser sysUser, List<Long> roleList) {
        ServiceResult<SysUser> serviceResult = new ServiceResult<>();
        SysUser user = lambdaQuery().ne(SysUser::getId,sysUser.getId()).eq(SysUser::getUsername, sysUser.getUsername()).one();
        if(user != null) {
            serviceResult.setError(AccountExcpConstants.ERROR_CODE_USER_NAME_EXISTS,AccountExcpConstants.ERROR_MSG_USER_NAME_EXISTS);
            return serviceResult;
        }
        user = lambdaQuery().ne(SysUser::getId,sysUser.getId()).eq(SysUser::getPhone, sysUser.getPhone()).one();
        if(user != null) {
            serviceResult.setError(AccountExcpConstants.ERROR_CODE_USER_PHONE_EXISTS,AccountExcpConstants.ERROR_MSG_USER_PHONE_EXISTS);
            return serviceResult;
        }
        user = lambdaQuery().ne(SysUser::getId,sysUser.getId()).eq(SysUser::getEmail, sysUser.getEmail()).one();
        if(user != null) {
            serviceResult.setError(AccountExcpConstants.ERROR_CODE_USER_EMAIL_EXISTS,AccountExcpConstants.ERROR_MSG_USER_EMAIL_EXISTS);
            return serviceResult;
        }

        baseMapper.updateById(sysUser);
        if(roleList != null && !roleList.isEmpty()) {
            //移除之前的角色
            QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(CommonParams.DATA_BASE_USER_ID,sysUser.getId());
            userRoleService.remove(queryWrapper);
            //新增新角色
            List<SysUserRole> sysUserRoleList = generateUserRole(sysUser.getId(), roleList);
            userRoleService.saveBatch(sysUserRoleList);
        }
        serviceResult.setResult(sysUser);
        return serviceResult;
    }

    @Override
    public ServiceResult<IPage<SysUser>> findUserListByPage(int page, int limit, SysUser sysUser) {
        ServiceResult<IPage<SysUser>> serviceResult = new ServiceResult<>();
        Page<SysUser> sysUserPage = new Page<>(page, limit);
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(sysUser);
        IPage<SysUser> userIPage = baseMapper.selectPage(sysUserPage, queryWrapper);
        serviceResult.setResult(userIPage);
        return serviceResult;
    }

    @Override
    public ServiceResult<List<SysUser>> findUserList() {
        ServiceResult<List<SysUser>> serviceResult = new ServiceResult<>();
        List<SysUser> sysUserList = lambdaQuery().list();
        serviceResult.setResult(sysUserList);
        return serviceResult;
    }

    @Override
    public ServiceResult<SysUser> findUserById(Long userId) {
        ServiceResult<SysUser> serviceResult = new ServiceResult<>();
        SysUser sysUser = lambdaQuery().eq(SysUser::getId,userId).one();
        //查询用户角色信息
        List<SysUserRole> sysUserRoleList = userRoleService.lambdaQuery().eq(SysUserRole::getUserId, userId).list();
        if(sysUserRoleList != null && !sysUserRoleList.isEmpty()) {
            List<Long> roleIdList = sysUserRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
            sysUser.setRoleIdList(roleIdList);
        }

        serviceResult.setResult(sysUser);
        return serviceResult;
    }

    @Override
    public ServiceResult<Integer> deleteUserById(Long userId) {
        ServiceResult<Integer> serviceResult = new ServiceResult<>();
        //删除用户角色
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CommonParams.DATA_BASE_USER_ID,userId);
        userRoleService.remove(queryWrapper);
        //删除用户
        int result = baseMapper.deleteById(userId);
        serviceResult.setResult(result);
        return serviceResult;
    }

    private List<SysUserRole> generateUserRole(Long userId, List<Long> roleIdList) {
        List<SysUserRole> sysUserRoleList = roleIdList.stream().map(roleId -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(userId);
            sysUserRole.setRoleId(roleId);
            return sysUserRole;
        }).collect(Collectors.toList());
        return sysUserRoleList;
    }
}
